package com.example.nextgen.function;

import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.TypeReference;
import com.example.nextgen.event.Event;
import com.example.nextgen.event.EventSubscriber;
import com.example.nextgen.parser.excel.ExcelContext;
import com.example.nextgen.parser.excel.model.CellModel;
import com.example.nextgen.parser.excel.model.ExcelParserResult;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author martin
 * @date Created in 2022/11/9 20:03
 * @description 批注函数
 */
@Component
public class CommentFunction implements EventSubscriber {

    @Resource
    FunctionManager functionManager;

    LinkedHashMap<ExtendFunction, List<Pair<String,String>>> suspend = new LinkedHashMap<>();

    Pattern pattern = Pattern.compile("\\w+\\.\\w+\\(\\)");

    public Object getFunctionResult(CellModel cellModel){
        if (!cellModel.hasComment()){
            return cellModel.getContent().toString();
        }
        Matcher matcher = pattern.matcher(cellModel.getComment());
        List<String> functions = new ArrayList<>();
        while (matcher.find()){
            functions.add(matcher.group());
        }
        Object result = null;
        for (String function : functions) {
            String[] split = function.split("\\.");
            String object = split[0];
            String fun = split[1].replace("()","");
            String param = cellModel.getContent().toString();
            if (result != null) {
                param = result.toString();
            }
            ExtendFunction functionObject = functionManager.getFunction(object);
            if (functionObject.getRuntimeEvent() != null){
                List<Pair<String, String>> pairs = suspend.computeIfAbsent(functionObject, k -> new ArrayList<>());
                pairs.add(Pair.of(fun,param));
                return param;
            }
            result = functionManager.invoke(object, fun, param);
        }
        return result;
    }

    @Override
    public void onEvent(Event event) {
        ExtendFunction function = suspend.keySet().stream()
                .filter(extendFunction -> extendFunction.getRuntimeEvent() == event).findFirst().get();
        suspend.get(function).forEach(pair -> {
            ExcelParserResult excel = ExcelContext.getExcel();
            String param = pair.getValue();
            if (excel.hasNonComplete(param)){
                param = excel.refresh(param,excel.getDevelopForms(),new TypeReference<String>(){});
            }
            functionManager.invoke(function, pair.getKey(), param);
        });
        suspend.remove(function);
    }
}
